|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 00018 #include "derivative.h" 00019 #include "utils.h" 00020 #include <limits.h> 00021 /* 00022 ****************************************************************************** 00023 * constants 00024 ****************************************************************************** 00025 */ 00026 const uint8_t cau8OddParityTable[] = 00027 { 00028 /* This table gives the opposite of the calculated parity - it's what */ 00029 /* must be added in order to give the correct parity bit. */ 00030 /* 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F */ 00031 0u, 1u, 1u, 0u, 1u, 0u, 0u, 1u, 1u, 0u, 0u, 1u, 0u, 1u, 1u, 0u 00032 /* 1u, 0u, 0u, 1u, 0u, 1u, 1u, 0u, 0u, 1u, 1u, 0u, 1u, 0u, 0u, 1u*/ 00033 }; 00034 /* 00035 ****************************************************************************** 00036 * Globals 00037 ****************************************************************************** 00038 */ 00039 /* 00040 ****************************************************************************** 00041 * u8fnCheckOddParity 00042 ****************************************************************************** 00043 */ 00044 uint8_t u8fnCheckOddParity(uint8_t u8Byte, uint8_t u8ParityPosition) 00045 { 00046 /* LocalVariables */ 00047 uint8_t u8ParityLow; 00048 uint8_t u8ParityHigh; 00049 uint8_t u8Parity; 00050 00051 /* Calculate parity for each nibble in the byte */ 00052 u8ParityHigh = cau8OddParityTable[u8Byte >> BITS_IN_NIBBLE]; 00053 u8ParityLow = cau8OddParityTable[u8Byte & 0x0Fu]; 00054 00055 /* Combine both calculations using XOR: */ 00056 /* Even and even = Even */ 00057 /* Odd and odd = Even */ 00058 /* Even and odd = Odd */ 00059 /* Odd and even = Odd */ 00060 u8Parity = (u8ParityHigh ^ u8ParityLow); 00061 00062 /* If u8Parity is cleared, this means we currently hold even parity. */ 00063 if(CLEAR == u8Parity) 00064 { 00065 /* If a bit position is set for it, return u8Byte with its value */ 00066 if(CLEAR != u8ParityPosition) 00067 { 00068 u8Parity = (u8Byte | u8ParityPosition); 00069 } 00070 else 00071 { 00072 /* Make u8Parity 1 to signal we need to add one */ 00073 u8Parity = TRUE; 00074 } 00075 } 00076 else 00077 { 00078 /* Parity bit is set, meaning the byte is already odd parity */ 00079 if(CLEAR != u8ParityPosition) 00080 { 00081 /* Output the message without the parity bit set */ 00082 u8Parity = u8Byte; 00083 } 00084 else 00085 { 00086 /* Make u8Parity 0 to signal we don't need to add anything */ 00087 u8Parity = CLEAR; 00088 } 00089 } 00090 00091 return(u8Parity); 00092 } 00093 /* 00094 ****************************************************************************** 00095 * u16fnCheckOddParity 00096 ****************************************************************************** 00097 */ 00098 uint16_t u16fnCheckOddParity(uint16_t u16Word, uint16_t u16ParityPosition) 00099 { 00100 /* LocalVariables */ 00101 uint8_t u8ParityLow; 00102 uint8_t u8ParityHigh; 00103 uint16_t u16Parity; 00104 00105 /* Calculate parity for each byte in the word - the result is what we need */ 00106 /* to add to the word in order to make it odd parity. */ 00107 u8ParityHigh = u8fnCheckOddParity((uint8_t)(u16Word >> BITS_IN_BYTE), CLEAR); 00108 u8ParityLow = u8fnCheckOddParity((uint8_t)u16Word, CLEAR); 00109 00110 /* Combine both calculations with XNOR */ 00111 /* Parity bit needed + Parity bit needed = Parity bit needed */ 00112 /* Parity bit needed + Parity bit not needed = Parity bit not needed */ 00113 /* Parity bit not needed + Parity bit needed = Parity bit not needed */ 00114 /* Parity bit not needed + Parity bit not needed = Parity bit needed */ 00115 00116 u16Parity = !(u8ParityHigh ^ u8ParityLow); 00117 00118 00119 /* If a bit position is set for it, return u16Word with its value */ 00120 if(CLEAR != u16ParityPosition) 00121 { 00122 if(CLEAR != u16Parity) 00123 { 00124 u16Parity = (u16Word | u16ParityPosition); 00125 } 00126 else 00127 { 00128 u16Parity = u16Word; 00129 } 00130 } 00131 else 00132 { 00133 /* Just Output u16Parity */ 00134 } 00135 00136 return(u16Parity); 00137 } 00138 /* 00139 ****************************************************************************** 00140 * u32fnCheckOddParity 00141 ****************************************************************************** 00142 */ 00143 uint32_t u32fnCheckOddParity(uint32_t u32Word, uint32_t u32ParityPosition) 00144 { 00145 /* LocalVariables */ 00146 uint16_t u16ParityLow; 00147 uint16_t u16ParityHigh; 00148 uint32_t u32Parity; 00149 00150 /* Calculate parity for each byte in the word - the result is what we need */ 00151 /* to add to the word in order to make it odd parity. */ 00152 u16ParityHigh = u16fnCheckOddParity((uint16_t)(u32Word >> BITS_IN_16), CLEAR); 00153 u16ParityLow = u16fnCheckOddParity((uint16_t)u32Word, CLEAR); 00154 00155 /* Combine both calculations with XNOR */ 00156 /* Parity bit needed + Parity bit needed = Parity bit needed */ 00157 /* Parity bit needed + Parity bit not needed = Parity bit not needed */ 00158 /* Parity bit not needed + Parity bit needed = Parity bit not needed */ 00159 /* Parity bit not needed + Parity bit not needed = Parity bit needed */ 00160 00161 u32Parity = !(u16ParityHigh ^ u16ParityLow); 00162 00163 00164 /* If a bit position is set for it, return u32Word with its value */ 00165 if(CLEAR != u32ParityPosition) 00166 { 00167 if(CLEAR != u32Parity) 00168 { 00169 u32Parity = (u32Word | u32ParityPosition); 00170 } 00171 else 00172 { 00173 u32Parity = u32Word; 00174 } 00175 } 00176 else 00177 { 00178 /* Just Output u32Parity */ 00179 } 00180 00181 return(u32Parity); 00182 } 00183 /* 00184 ****************************************************************************** 00185 * u8fnCRC8 00186 ****************************************************************************** 00187 */ 00188 uint8_t u8fnCRC8(const uint8_t* pu8Buffer, uint8_t u8Poly, uint8_t u8MBitsize, \ 00189 uint8_t u8Remainder) 00190 { 00191 /* Local Variables */ 00192 uint8_t u8Value; 00193 uint8_t u8ucBit; 00194 uint8_t u8Count; 00195 uint8_t u8Polynomial; 00196 00197 u8Polynomial = u8Poly; 00198 u8Value = CLEAR; /* Initial value to make MISRA happy */ 00199 00200 for (u8Count = CLEAR; u8Count < u8MBitsize; u8Count++) 00201 { 00202 /* End of 8 bits process ? */ 00203 if ((u8Count & MSB_MINUS_ONE) == CLEAR) 00204 { 00205 /* get next buffer value */ 00206 u8Value = pu8Buffer[(u8Count / BITS_IN_BYTE)]; 00207 } 00208 else 00209 { 00210 /* Do nothing */ 00211 } 00212 00213 u8ucBit = u8Value ^ u8Remainder; 00214 u8Remainder = ((uint8_t)(u8Remainder << 1u)); 00215 00216 /* MSB CRC bit <> MSB Value bit ? */ 00217 if(u8ucBit & MSB_8_BITS) 00218 { 00219 u8Remainder ^= u8Polynomial; 00220 } 00221 else 00222 { 00223 /* Do nothing */ 00224 } 00225 u8Value = ((uint8_t)(u8Value << 1u)); 00226 } 00227 00228 return(u8Remainder); 00229 } 00230 /* 00231 ****************************************************************************** 00232 * vfnHexToASCII 00233 ****************************************************************************** 00234 */ 00235 void vfnASCIIByteToHex(uint8_t* pu8Source, uint8_t* pu8Target, 00236 uint16_t u16NOfBytes) 00237 { 00238 for(; u16NOfBytes > CLEAR; u16NOfBytes--) 00239 { 00240 /* Start with the upper nibble */ 00241 *pu8Target = u8fnUnitASCIIToHex(*pu8Source); 00242 /* Increment Target index */ 00243 pu8Target++; 00244 pu8Source++; 00245 } 00246 00247 return; 00248 } 00249 /* 00250 ****************************************************************************** 00251 * u8fnUnitASCIIToHex 00252 ****************************************************************************** 00253 */ 00254 static uint8_t u8fnUnitASCIIToHex(const uint8_t u8ASCIIData) 00255 { 00256 uint8_t u8Offset; 00257 00258 u8Offset = CLEAR; 00259 00260 if((u8ASCIIData >= 'A') & (u8ASCIIData <= 'Z')) 00261 { 00262 u8Offset = ('A' - (uint8_t)0x0Au); 00263 } 00264 else if((u8ASCIIData >= 'a') & (u8ASCIIData <= 'z')) 00265 { 00266 u8Offset = ('a' - (uint8_t)0x0Au); 00267 } 00268 else if((u8ASCIIData >= '0') & (u8ASCIIData <= '9')) 00269 { 00270 u8Offset = '0'; 00271 } 00272 else 00273 { 00274 /* Keep the value as it is */ 00275 } 00276 00277 return(u8ASCIIData - u8Offset); 00278 } 00279 /* 00280 ****************************************************************************** 00281 * vfnHexToASCIIMaskToList 00282 ****************************************************************************** 00283 */ 00284 void vfnHexToASCIIMaskToList(const uint16_t cu16MaskList, 00285 uint8_t* pau8DataArray, 00286 uint16_t* pu16Index, 00287 const uint16_t cu16Mask) 00288 { 00289 uint8_t u8Counter; 00290 00291 u8Counter = CLEAR; 00292 00293 for(u8Counter = 1u; u8Counter < 16; u8Counter++) 00294 { 00295 if(cu16Mask & (BIT0 << u8Counter)) 00296 { 00297 break; 00298 } 00299 else 00300 { 00301 /* loop */ 00302 } 00303 } 00304 00305 if(cu16MaskList & cu16Mask) 00306 { 00307 pau8DataArray[(*pu16Index)++] = u8fnUnitHexToASCII(u8Counter); 00308 *(pau8DataArray + (*pu16Index)++) = ','; 00309 *(pau8DataArray + (*pu16Index)++) = ' '; 00310 } 00311 else 00312 { 00313 /* Nothing */ 00314 } 00315 00316 return; 00317 } 00318 /* 00319 ****************************************************************************** 00320 * vfnHexToASCII 00321 ****************************************************************************** 00322 */ 00323 void vfnHexToASCII(uint8_t* pu8Source, uint8_t* pu8Target, \ 00324 uint16_t u16NOfBytes) 00325 { 00326 for(; u16NOfBytes > CLEAR; u16NOfBytes--) 00327 { 00328 /* Start with the upper nibble */ 00329 *pu8Target = u8fnUnitHexToASCII(*pu8Source >> BITS_IN_NIBBLE); 00330 /* Increment Target index */ 00331 pu8Target++; 00332 00333 /* Continue with the lower nibble */ 00334 *pu8Target = u8fnUnitHexToASCII(*pu8Source & 0x0Fu); 00335 /* Increment both indeces */ 00336 pu8Target++; 00337 pu8Source++; 00338 } 00339 00340 return; 00341 } 00342 /* 00343 ****************************************************************************** 00344 * u8fnUnitHexToASCII 00345 ****************************************************************************** 00346 */ 00347 static uint8_t u8fnUnitHexToASCII(uint8_t u8HexData) 00348 { 00349 /* Declare local variables */ 00350 uint8_t u8ASCII; 00351 00352 /* Init local variables */ 00353 u8ASCII = CLEAR; 00354 00355 /* Only look at lower nibble */ 00356 u8HexData &= 0x0F; 00357 00358 /* Translate */ 00359 if (u8HexData < 0x0A) 00360 { 00361 u8ASCII = (uint8_t)(u8HexData + '0'); 00362 } 00363 else 00364 { 00365 u8ASCII = (uint8_t)((u8HexData - 0x0Au) + 'A'); 00366 } 00367 00368 return (u8ASCII); 00369 } 00370 /* 00371 ****************************************************************************** 00372 * vfnCopyArray 00373 ****************************************************************************** 00374 */ 00375 void vfnCopyArray(uint8_t* pu8Source, uint8_t* pu8Target, \ 00376 uint16_t u16NOfBytes) 00377 { 00378 for(; u16NOfBytes > CLEAR; u16NOfBytes--) 00379 { 00380 /* Start with the upper nibble */ 00381 *pu8Target = *pu8Source; 00382 /* Increment Target index + Source */ 00383 pu8Target++; 00384 pu8Source++; 00385 } 00386 00387 return; 00388 } 00389 /* 00390 ****************************************************************************** 00391 * Function: u16fnMaxU16DeltaInArray 00392 *****************************************************************************/ 00393 uint16_t u16fnMaxU16DeltaInArray(const uint16_t* au16Array, uint8_t u8ArraySize) 00394 { 00395 /* Declare Local Variables */ 00396 uint16_t u16Max; 00397 uint16_t u16Min; 00398 00399 /* Init local variables */ 00400 u16Max = CLEAR; 00401 u16Min = USHRT_MAX; 00402 00403 /* Loop from last location to the second one (ignores the first one) */ 00404 for(--u8ArraySize; u8ArraySize != UCHAR_MAX; u8ArraySize--) 00405 { 00406 /* Search for Array Max */ 00407 if(u16Max < au16Array[u8ArraySize]) 00408 { 00409 u16Max = au16Array[u8ArraySize]; 00410 } 00411 else 00412 { 00413 /* Do nothing */ 00414 } 00415 00416 /* Search for Array Min */ 00417 if(u16Min > au16Array[u8ArraySize]) 00418 { 00419 u16Min = au16Array[u8ArraySize]; 00420 } 00421 else 00422 { 00423 /* Do nothing */ 00424 } 00425 }/* End for loop */ 00426 00427 /* Find Max Delta and return it */ 00428 return (u16Max - u16Min); 00429 } 00430 /* 00431 ****************************************************************************** 00432 * Function: u32fnDiffAbsoluteValue 00433 *****************************************************************************/ 00434 uint32_t u32fnDiffAbsoluteValue(uint32_t au32Value1, uint32_t au32Value2) 00435 { 00436 /* Declare Local Variables */ 00437 uint32_t u32Result; 00438 00439 if(au32Value1 > au32Value2) 00440 { 00441 u32Result = au32Value1 - au32Value2; 00442 } 00443 else 00444 { 00445 u32Result = au32Value2 - au32Value1; 00446 } 00447 00448 /* Return Absolute Value of the difference */ 00449 return (u32Result); 00450 } 00451 /* 00452 ****************************************************************************** 00453 * 00454 * End of file. 00455 * 00456 ****************************************************************************** 00457 */